package com.lsc.record.handler;

import java.util.Objects;

import javax.validation.ValidationException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lsc.record.config.ApiResult;

import lombok.SneakyThrows;

@SuppressWarnings("rawtypes")
@RestControllerAdvice
public class ControllerExceptionHandel implements ResponseBodyAdvice<Object> {
    private static final Logger log = LoggerFactory.getLogger("exception");
    @Autowired
    private ObjectMapper objectMapper;

    @ExceptionHandler(ValidationException.class)
    public ApiResult<String> handleException(ValidationException e) {
        e.printStackTrace();
        log.error("参数校验发生异常:{}", e.getMessage());
        return ApiResult.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @ExceptionHandler(value = NullPointerException.class)
    public ApiResult<String> exceptionHandler(NullPointerException e) {
        e.printStackTrace();
        log.error("空指针异常:{}", e.getMessage());
        return ApiResult.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(value = {Exception.class, RuntimeException.class})
    public ApiResult<String> exceptionHandler(Exception e) {
        e.printStackTrace();
        log.error("运行时发生异常:{}", e.getMessage());
        return ApiResult.failure(HttpStatus.INTERNAL_SERVER_ERROR.value(), e.getMessage());
    }

    @ExceptionHandler(AsyncRequestTimeoutException.class)
    public ApiResult<String> handException(AsyncRequestTimeoutException e) {
        e.printStackTrace();
        log.error("运行时超时异常:{}", e.getMessage());
        return ApiResult.failure(HttpStatus.BAD_REQUEST.value(), e.getMessage());
    }

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    
	@SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {

        Class<?> returnClass = returnType.getMethod().getReturnType();
        if (body instanceof String || Objects.equals(returnClass, String.class)) {
            return objectMapper.writeValueAsString(ApiResult.success(body));
        }
        if (body instanceof ApiResult) {
            return body;
        }
        return ApiResult.success(body);
    }
}
